/*
===========================================================================

Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.

This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").

Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.

In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.

If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.

===========================================================================
*/

#include "Precompiled.h"
#include "globaldata.h"





#include <stdlib.h>

#include "i_system.h"

#include "doomdef.h"
#include "doomstat.h"

#include "r_local.h"
#include "r_sky.h"


// OPTIMIZE: closed two sided ::g->lines as single sided

// True if any of the ::g->segs textures might be visible.

// False if the back side is the same plane.



// angle to line origin

//
// regular wall
//










//
// R_RenderMaskedSegRange
//
void
R_RenderMaskedSegRange
( drawseg_t*	ds,
  int		x1,
  int		x2 )
{
	unsigned		index;
	postColumn_t*	col;
	int				lightnum;
	int				texnum;

	// Calculate light table.
	// Use different light tables
	//   for horizontal / vertical / diagonal. Diagonal?
	// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
	::g->curline = ds->curline;
	::g->frontsector = ::g->curline->frontsector;
	::g->backsector = ::g->curline->backsector;
	texnum = ::g->texturetranslation[::g->curline->sidedef->midtexture];

	lightnum = ( ::g->frontsector->lightlevel >> LIGHTSEGSHIFT ) +::g->extralight;

	if( ::g->curline->v1->y == ::g->curline->v2->y )
	{
		lightnum--;
	}
	else if( ::g->curline->v1->x == ::g->curline->v2->x )
	{
		lightnum++;
	}

	if( lightnum < 0 )
	{
		::g->walllights = ::g->scalelight[0];
	}
	else if( lightnum >= LIGHTLEVELS )
	{
		::g->walllights = ::g->scalelight[LIGHTLEVELS - 1];
	}
	else
	{
		::g->walllights = ::g->scalelight[lightnum];
	}

	::g->maskedtexturecol = ds->maskedtexturecol;

	::g->rw_scalestep = ds->scalestep;
	::g->spryscale = ds->scale1 + ( x1 - ds->x1 )*::g->rw_scalestep;
	::g->mfloorclip = ds->sprbottomclip;
	::g->mceilingclip = ds->sprtopclip;

	// find positioning
	if( ::g->curline->linedef->flags & ML_DONTPEGBOTTOM )
	{
		::g->dc_texturemid = ::g->frontsector->floorheight > ::g->backsector->floorheight
							 ? ::g->frontsector->floorheight : ::g->backsector->floorheight;
		::g->dc_texturemid = ::g->dc_texturemid + ::g->s_textureheight[texnum] - ::g->viewz;
	}
	else
	{
		::g->dc_texturemid =::g->frontsector->ceilingheight < ::g->backsector->ceilingheight
							? ::g->frontsector->ceilingheight : ::g->backsector->ceilingheight;
		::g->dc_texturemid = ::g->dc_texturemid - ::g->viewz;
	}
	::g->dc_texturemid += ::g->curline->sidedef->rowoffset;

	if( ::g->fixedcolormap )
	{
		::g->dc_colormap = ::g->fixedcolormap;
	}

	// draw the columns
	for( ::g->dc_x = x1 ; ::g->dc_x <= x2 ; ::g->dc_x++ )
	{
		// calculate lighting
		if( ::g->maskedtexturecol[::g->dc_x] != SHRT_MAX )
		{
			if( !::g->fixedcolormap )
			{
				index = ::g->spryscale >> LIGHTSCALESHIFT;

				if( index >=  MAXLIGHTSCALE )
				{
					index = MAXLIGHTSCALE - 1;
				}

				::g->dc_colormap = ::g->walllights[index];
			}

			::g->sprtopscreen = ::g->centeryfrac - FixedMul( ::g->dc_texturemid, ::g->spryscale );
			::g->dc_iscale = 0xffffffffu / ( unsigned )::g->spryscale;

			// draw the texture
			col = ( postColumn_t* )(
					  ( byte* )R_GetColumn( texnum, ::g->maskedtexturecol[::g->dc_x] ) - 3 );

			R_DrawMaskedColumn( col );
			::g->maskedtexturecol[::g->dc_x] = SHRT_MAX;
		}
		::g->spryscale += ::g->rw_scalestep;
	}

}




//
// R_RenderSegLoop
// Draws zero, one, or two textures (and possibly a masked
//  texture) for walls.
// Can draw or mark the starting pixel of floor and ceiling
//  textures.
// CALLED: CORE LOOPING ROUTINE.
//

void R_RenderSegLoop( void )
{
	angle_t		angle;
	unsigned		index;
	int			yl;
	int			yh;
	int			mid;
	fixed_t		texturecolumn;
	int			top;
	int			bottom;

	texturecolumn = 0;				// shut up compiler warning

	for( ; ::g->rw_x < ::g->rw_stopx ; ::g->rw_x++ )
	{
		// mark floor / ceiling areas
		yl = ( ::g->topfrac + HEIGHTUNIT - 1 ) >> HEIGHTBITS;

		// no space above wall?
		if( yl < ::g->ceilingclip[::g->rw_x] + 1 )
		{
			yl = ::g->ceilingclip[::g->rw_x] + 1;
		}

		if( ::g->markceiling )
		{
			top = ::g->ceilingclip[::g->rw_x] + 1;
			bottom = yl - 1;

			if( bottom >= ::g->floorclip[::g->rw_x] )
			{
				bottom = ::g->floorclip[::g->rw_x] - 1;
			}

			if( top <= bottom )
			{
				::g->ceilingplane->top[::g->rw_x] = top;
				::g->ceilingplane->bottom[::g->rw_x] = bottom;
			}
		}

		yh = ::g->bottomfrac >> HEIGHTBITS;

		if( yh >= ::g->floorclip[::g->rw_x] )
		{
			yh = ::g->floorclip[::g->rw_x] - 1;
		}

		if( ::g->markfloor )
		{
			top = yh + 1;
			bottom = ::g->floorclip[::g->rw_x] - 1;
			if( top <= ::g->ceilingclip[::g->rw_x] )
			{
				top = ::g->ceilingclip[::g->rw_x] + 1;
			}
			if( top <= bottom )
			{
				::g->floorplane->top[::g->rw_x] = top;
				::g->floorplane->bottom[::g->rw_x] = bottom;
			}
		}

		// texturecolumn and lighting are independent of wall tiers
		if( ::g->segtextured )
		{
			// calculate texture offset
			angle = ( ::g->rw_centerangle + ::g->xtoviewangle[::g->rw_x] ) >> ANGLETOFINESHIFT;
			texturecolumn = ::g->rw_offset - FixedMul( finetangent[angle], ::g->rw_distance );
			texturecolumn >>= FRACBITS;
			// calculate lighting
			index = ::g->rw_scale >> LIGHTSCALESHIFT;

			if( index >=  MAXLIGHTSCALE )
			{
				index = MAXLIGHTSCALE - 1;
			}

			::g->dc_colormap = ::g->walllights[index];
			::g->dc_x = ::g->rw_x;
			::g->dc_iscale = 0xffffffffu / ( unsigned )::g->rw_scale;
		}

		// draw the wall tiers
		if( ::g->midtexture )
		{
			// single sided line
			::g->dc_yl = yl;
			::g->dc_yh = yh;
			::g->dc_texturemid = ::g->rw_midtexturemid;
			::g->dc_source = R_GetColumn( ::g->midtexture, texturecolumn );
			colfunc( ::g->dc_colormap, ::g->dc_source );
			::g->ceilingclip[::g->rw_x] = ::g->viewheight;
			::g->floorclip[::g->rw_x] = -1;
		}
		else
		{
			// two sided line
			if( ::g->toptexture )
			{
				// top wall
				mid = ::g->pixhigh >> HEIGHTBITS;
				::g->pixhigh += ::g->pixhighstep;

				if( mid >= ::g->floorclip[::g->rw_x] )
				{
					mid = ::g->floorclip[::g->rw_x] - 1;
				}

				if( mid >= yl )
				{
					::g->dc_yl = yl;
					::g->dc_yh = mid;
					::g->dc_texturemid = ::g->rw_toptexturemid;
					::g->dc_source = R_GetColumn( ::g->toptexture, texturecolumn );
					colfunc( ::g->dc_colormap, ::g->dc_source );
					::g->ceilingclip[::g->rw_x] = mid;
				}
				else
				{
					::g->ceilingclip[::g->rw_x] = yl - 1;
				}
			}
			else
			{
				// no top wall
				if( ::g->markceiling )
				{
					::g->ceilingclip[::g->rw_x] = yl - 1;
				}
			}

			if( ::g->bottomtexture )
			{
				// bottom wall
				mid = ( ::g->pixlow + HEIGHTUNIT - 1 ) >> HEIGHTBITS;
				::g->pixlow += ::g->pixlowstep;

				// no space above wall?
				if( mid <= ::g->ceilingclip[::g->rw_x] )
				{
					mid = ::g->ceilingclip[::g->rw_x] + 1;
				}

				if( mid <= yh )
				{
					::g->dc_yl = mid;
					::g->dc_yh = yh;
					::g->dc_texturemid = ::g->rw_bottomtexturemid;
					::g->dc_source = R_GetColumn( ::g->bottomtexture,
												  texturecolumn );
					colfunc( ::g->dc_colormap, ::g->dc_source );
					::g->floorclip[::g->rw_x] = mid;
				}
				else
				{
					::g->floorclip[::g->rw_x] = yh + 1;
				}
			}
			else
			{
				// no bottom wall
				if( ::g->markfloor )
				{
					::g->floorclip[::g->rw_x] = yh + 1;
				}
			}

			if( ::g->maskedtexture )
			{
				// save texturecol
				//  for backdrawing of masked mid texture
				::g->maskedtexturecol[::g->rw_x] = texturecolumn;
			}
		}

		::g->rw_scale += ::g->rw_scalestep;
		::g->topfrac += ::g->topstep;
		::g->bottomfrac += ::g->bottomstep;
	}
}




//
// R_StoreWallRange
// A wall segment will be drawn
//  between start and stop pixels (inclusive).
//
void
R_StoreWallRange
( int	start,
  int	stop )
{
	fixed_t		hyp;
	fixed_t		sineval;
	angle_t		distangle, offsetangle;
	fixed_t		vtop;
	int			lightnum;

	// don't overflow and crash
	if( ::g->ds_p == &::g->drawsegs[MAXDRAWSEGS] )
	{
		return;
	}

#ifdef RANGECHECK
	if( start >=::g->viewwidth || start > stop )
	{
		I_Error( "Bad R_RenderWallRange: %i to %i", start , stop );
	}
#endif

	::g->sidedef = ::g->curline->sidedef;
	::g->linedef = ::g->curline->linedef;

	// mark the segment as visible for auto map
	::g->linedef->flags |= ML_MAPPED;

	// calculate ::g->rw_distance for scale calculation
	::g->rw_normalangle = ::g->curline->angle + ANG90;
	offsetangle = abs( ( int )( ::g->rw_normalangle -::g->rw_angle1 ) );

	if( offsetangle > ANG90 )
	{
		offsetangle = ANG90;
	}

	distangle = ANG90 - offsetangle;
	hyp = R_PointToDist( ::g->curline->v1->x, ::g->curline->v1->y );
	sineval = finesine[distangle >> ANGLETOFINESHIFT];
	::g->rw_distance = FixedMul( hyp, sineval );


	::g->ds_p->x1 = ::g->rw_x = start;
	::g->ds_p->x2 = stop;
	::g->ds_p->curline = ::g->curline;
	::g->rw_stopx = stop + 1;

	// calculate scale at both ends and step
	extern angle_t GetViewAngle();
	::g->ds_p->scale1 = ::g->rw_scale =
							R_ScaleFromGlobalAngle( GetViewAngle() + ::g->xtoviewangle[start] );

	if( stop > start )
	{
		::g->ds_p->scale2 = R_ScaleFromGlobalAngle( GetViewAngle() + ::g->xtoviewangle[stop] );
		::g->ds_p->scalestep = ::g->rw_scalestep =
								   ( ::g->ds_p->scale2 - ::g->rw_scale ) / ( stop - start );
	}
	else
	{
		// UNUSED: try to fix the stretched line bug
#if 0
		if( ::g->rw_distance < FRACUNIT / 2 )
		{
			fixed_t		trx, try;
			fixed_t		gxt, gyt;

			extern fixed_t GetViewX();
			extern fixed_t GetViewY();
			trx = ::g->curline->v1->x - GetViewX();
			try = ::g->curline->v1->y - GetVewY();

			gxt = FixedMul( trx, ::g->viewcos );
			gyt = -FixedMul( try, ::g->viewsin );
			::g->ds_p->scale1 = FixedDiv( ::g->projection, gxt - gyt ) << ::g->detailshift;
		}
#endif
		::g->ds_p->scale2 = ::g->ds_p->scale1;
	}

	// calculate texture boundaries
	//  and decide if floor / ceiling marks are needed
	::g->worldtop = ::g->frontsector->ceilingheight - ::g->viewz;
	::g->worldbottom = ::g->frontsector->floorheight - ::g->viewz;

	::g->midtexture = ::g->toptexture = ::g->bottomtexture = ::g->maskedtexture = 0;
	::g->ds_p->maskedtexturecol = NULL;

	if( !::g->backsector )
	{
		// single sided line
		::g->midtexture = ::g->texturetranslation[::g->sidedef->midtexture];
		// a single sided line is terminal, so it must mark ends
		::g->markfloor = ::g->markceiling = true;
		if( ::g->linedef->flags & ML_DONTPEGBOTTOM )
		{
			vtop = ::g->frontsector->floorheight +
				   ::g->s_textureheight[::g->sidedef->midtexture];
			// bottom of texture at bottom
			::g->rw_midtexturemid = vtop - ::g->viewz;
		}
		else
		{
			// top of texture at top
			::g->rw_midtexturemid = ::g->worldtop;
		}
		::g->rw_midtexturemid += ::g->sidedef->rowoffset;

		::g->ds_p->silhouette = SIL_BOTH;
		::g->ds_p->sprtopclip = ::g->screenheightarray;
		::g->ds_p->sprbottomclip = ::g->negonearray;
		::g->ds_p->bsilheight = MAXINT;
		::g->ds_p->tsilheight = MININT;
	}
	else
	{
		// two sided line
		::g->ds_p->sprtopclip = ::g->ds_p->sprbottomclip = NULL;
		::g->ds_p->silhouette = 0;

		if( ::g->frontsector->floorheight > ::g->backsector->floorheight )
		{
			::g->ds_p->silhouette = SIL_BOTTOM;
			::g->ds_p->bsilheight = ::g->frontsector->floorheight;
		}
		else if( ::g->backsector->floorheight > ::g->viewz )
		{
			::g->ds_p->silhouette = SIL_BOTTOM;
			::g->ds_p->bsilheight = MAXINT;
			// ::g->ds_p->sprbottomclip = ::g->negonearray;
		}

		if( ::g->frontsector->ceilingheight < ::g->backsector->ceilingheight )
		{
			::g->ds_p->silhouette |= SIL_TOP;
			::g->ds_p->tsilheight = ::g->frontsector->ceilingheight;
		}
		else if( ::g->backsector->ceilingheight < ::g->viewz )
		{
			::g->ds_p->silhouette |= SIL_TOP;
			::g->ds_p->tsilheight = MININT;
			// ::g->ds_p->sprtopclip = ::g->screenheightarray;
		}

		if( ::g->backsector->ceilingheight <= ::g->frontsector->floorheight )
		{
			::g->ds_p->sprbottomclip = ::g->negonearray;
			::g->ds_p->bsilheight = MAXINT;
			::g->ds_p->silhouette |= SIL_BOTTOM;
		}

		if( ::g->backsector->floorheight >= ::g->frontsector->ceilingheight )
		{
			::g->ds_p->sprtopclip = ::g->screenheightarray;
			::g->ds_p->tsilheight = MININT;
			::g->ds_p->silhouette |= SIL_TOP;
		}

		::g->worldhigh = ::g->backsector->ceilingheight - ::g->viewz;
		::g->worldlow = ::g->backsector->floorheight - ::g->viewz;

		// hack to allow height changes in outdoor areas
		if( ::g->frontsector->ceilingpic == ::g->skyflatnum
				&& ::g->backsector->ceilingpic == ::g->skyflatnum )
		{
			::g->worldtop = ::g->worldhigh;
		}


		if( ::g->worldlow != ::g->worldbottom
				|| ::g->backsector->floorpic != ::g->frontsector->floorpic
				|| ::g->backsector->lightlevel != ::g->frontsector->lightlevel )
		{
			::g->markfloor = true;
		}
		else
		{
			// same plane on both ::g->sides
			::g->markfloor = false;
		}


		if( ::g->worldhigh != ::g->worldtop
				|| ::g->backsector->ceilingpic != ::g->frontsector->ceilingpic
				|| ::g->backsector->lightlevel != ::g->frontsector->lightlevel )
		{
			::g->markceiling = true;
		}
		else
		{
			// same plane on both ::g->sides
			::g->markceiling = false;
		}

		if( ::g->backsector->ceilingheight <= ::g->frontsector->floorheight
				|| ::g->backsector->floorheight >= ::g->frontsector->ceilingheight )
		{
			// closed door
			::g->markceiling = ::g->markfloor = true;
		}


		if( ::g->worldhigh < ::g->worldtop )
		{
			// top texture
			::g->toptexture = ::g->texturetranslation[::g->sidedef->toptexture];
			if( ::g->linedef->flags & ML_DONTPEGTOP )
			{
				// top of texture at top
				::g->rw_toptexturemid = ::g->worldtop;
			}
			else
			{
				vtop =
					::g->backsector->ceilingheight
					+ ::g->s_textureheight[::g->sidedef->toptexture];

				// bottom of texture
				::g->rw_toptexturemid = vtop - ::g->viewz;
			}
		}
		if( ::g->worldlow > ::g->worldbottom )
		{
			// bottom texture
			::g->bottomtexture = ::g->texturetranslation[::g->sidedef->bottomtexture];

			if( ::g->linedef->flags & ML_DONTPEGBOTTOM )
			{
				// bottom of texture at bottom
				// top of texture at top
				::g->rw_bottomtexturemid = ::g->worldtop;
			}
			else	// top of texture at top
			{
				::g->rw_bottomtexturemid = ::g->worldlow;
			}
		}
		::g->rw_toptexturemid += ::g->sidedef->rowoffset;
		::g->rw_bottomtexturemid += ::g->sidedef->rowoffset;

		// allocate space for masked texture tables
		if( ::g->sidedef->midtexture )
		{
			// masked ::g->midtexture
			::g->maskedtexture = true;
			::g->ds_p->maskedtexturecol = ::g->maskedtexturecol = ::g->lastopening - ::g->rw_x;
			::g->lastopening += ::g->rw_stopx - ::g->rw_x;
		}
	}

	// calculate ::g->rw_offset (only needed for textured ::g->lines)
	::g->segtextured = ::g->midtexture | ::g->toptexture | ::g->bottomtexture | ::g->maskedtexture;

	if( ::g->segtextured )
	{
		offsetangle = ::g->rw_normalangle -::g->rw_angle1;

		if( offsetangle > ANG180 )
		{
			offsetangle = UINT_MAX - offsetangle + 1;	// ALANHACK UNSIGNED, SRS - make uint math explicit
		}

		if( offsetangle > ANG90 )
		{
			offsetangle = ANG90;
		}

		sineval = finesine[offsetangle >> ANGLETOFINESHIFT];
		::g->rw_offset = FixedMul( hyp, sineval );

		if( ::g->rw_normalangle -::g->rw_angle1 < ANG180 )
		{
			::g->rw_offset = -::g->rw_offset;
		}

		::g->rw_offset += ::g->sidedef->textureoffset + ::g->curline->offset;
		::g->rw_centerangle = ANG90 + GetViewAngle() - ::g->rw_normalangle;

		// calculate light table
		//  use different light tables
		//  for horizontal / vertical / diagonal
		// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
		if( !::g->fixedcolormap )
		{
			lightnum = ( ::g->frontsector->lightlevel >> LIGHTSEGSHIFT ) +::g->extralight;

			if( ::g->curline->v1->y == ::g->curline->v2->y )
			{
				lightnum--;
			}
			else if( ::g->curline->v1->x == ::g->curline->v2->x )
			{
				lightnum++;
			}

			if( lightnum < 0 )
			{
				::g->walllights = ::g->scalelight[0];
			}
			else if( lightnum >= LIGHTLEVELS )
			{
				::g->walllights = ::g->scalelight[LIGHTLEVELS - 1];
			}
			else
			{
				::g->walllights = ::g->scalelight[lightnum];
			}
		}
	}

	// if a floor / ceiling plane is on the wrong side
	//  of the view plane, it is definitely invisible
	//  and doesn't need to be marked.


	if( ::g->frontsector->floorheight >= ::g->viewz )
	{
		// above view plane
		::g->markfloor = false;
	}

	if( ::g->frontsector->ceilingheight <= ::g->viewz
			&& ::g->frontsector->ceilingpic != ::g->skyflatnum )
	{
		// below view plane
		::g->markceiling = false;
	}


	// calculate incremental stepping values for texture edges
	::g->worldtop >>= 4;
	::g->worldbottom >>= 4;

	::g->topstep = -FixedMul( ::g->rw_scalestep, ::g->worldtop );
	::g->topfrac = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldtop, ::g->rw_scale );

	::g->bottomstep = -FixedMul( ::g->rw_scalestep, ::g->worldbottom );
	::g->bottomfrac = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldbottom, ::g->rw_scale );

	if( ::g->backsector )
	{
		::g->worldhigh >>= 4;
		::g->worldlow >>= 4;

		if( ::g->worldhigh < ::g->worldtop )
		{
			::g->pixhigh = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldhigh, ::g->rw_scale );
			::g->pixhighstep = -FixedMul( ::g->rw_scalestep, ::g->worldhigh );
		}

		if( ::g->worldlow > ::g->worldbottom )
		{
			::g->pixlow = ( ::g->centeryfrac >> 4 ) - FixedMul( ::g->worldlow, ::g->rw_scale );
			::g->pixlowstep = -FixedMul( ::g->rw_scalestep, ::g->worldlow );
		}
	}

	// render it
	if( ::g->markceiling )
	{
		::g->ceilingplane = R_CheckPlane( ::g->ceilingplane, ::g->rw_x, ::g->rw_stopx - 1 );
	}

	if( ::g->markfloor )
	{
		::g->floorplane = R_CheckPlane( ::g->floorplane, ::g->rw_x, ::g->rw_stopx - 1 );
	}

	R_RenderSegLoop();


	// save sprite clipping info
	if( ( ( ::g->ds_p->silhouette & SIL_TOP ) || ::g->maskedtexture )
			&& !::g->ds_p->sprtopclip )
	{
		memcpy( ::g->lastopening, ::g->ceilingclip + start, 2 * ( ::g->rw_stopx - start ) );
		::g->ds_p->sprtopclip = ::g->lastopening - start;
		::g->lastopening += ::g->rw_stopx - start;
	}

	if( ( ( ::g->ds_p->silhouette & SIL_BOTTOM ) || ::g->maskedtexture )
			&& !::g->ds_p->sprbottomclip )
	{
		memcpy( ::g->lastopening, ::g->floorclip + start, 2 * ( ::g->rw_stopx - start ) );
		::g->ds_p->sprbottomclip = ::g->lastopening - start;
		::g->lastopening += ::g->rw_stopx - start;
	}

	if( ::g->maskedtexture && !( ::g->ds_p->silhouette & SIL_TOP ) )
	{
		::g->ds_p->silhouette |= SIL_TOP;
		::g->ds_p->tsilheight = MININT;
	}
	if( ::g->maskedtexture && !( ::g->ds_p->silhouette & SIL_BOTTOM ) )
	{
		::g->ds_p->silhouette |= SIL_BOTTOM;
		::g->ds_p->bsilheight = MAXINT;
	}
	::g->ds_p++;
}


